﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WASapTKB.Domain;

namespace WASapTKB
{
    public partial class FrmGAMain : Form
    {
        public FrmGAMain()
        {
            InitializeComponent();

            // Khởi tạo combobox các phòng.
            for (int i = 0; i < inputData.NumRoom; i++)
            {
                cbbRoom.Items.Add(i + 1);
            }
            bntStart.Focus();
        }
        private InputData inputData = InputData.Instance();
        GenericAlgorithm oGenericAlgorithm;

        #region Giải mã dữ liệu
        // Giải mã thời khóa biểu.
        string ConvertSchedule(List<int> pSchedule)
        {
            string result = string.Empty;
            string sUnit, sEvent;
            for (int i = 0; i < pSchedule.Count; i++)
            {
                sUnit = ConvertUnit(i);
                sEvent = ConvertEventValue(pSchedule[i]);
                result += sUnit + "->" + sEvent + "\r\n";
            }
            return result;
        }
        // Giải mã tiết.
        string ConvertUnit(int pUnitValueTotal)
        {
            string result = "[";
            int iUnitValue = inputData.indexUnitValue(pUnitValueTotal);
            result += "Phong_" + inputData.indexRoom(pUnitValueTotal);
            result += " | ";
            result += "Thu_" + (iUnitValue / (inputData.NumSession * inputData.NumPeriod)) + 2;
            result += " | ";
            result += "Buoi_" + (iUnitValue % (inputData.NumSession * inputData.NumPeriod)) / 5;
            result += " | ";
            result += "Tiet_" + (iUnitValue % (inputData.NumSession * inputData.NumPeriod)) % 5;
            result += "]";
            return result;
        }
        // Giải mã giá trị sự kiện.
        string ConvertEventValue(int pEventValue)
        {
            if (pEventValue == -1)
                return string.Empty;
            string result = "[";
            result += inputData.indexTeacher(pEventValue);
            result += ",";
            result += inputData.indexClass(pEventValue);
            result += ",";
            result += inputData.indexSubject(pEventValue);
            result += "]";
            return result;
        }
        #endregion Giải mã dữ liệu

        #region Tương tác với người dùng.
        // Bắt đầu chạy giải thuật.
        private void bntStart_Click(object sender, EventArgs e)
        {
            bntStart.Enabled = cbbRoom.Enabled = false;
            dataGridView1.DataSource = null;
            cbbRoom.SelectedIndex = -1;
            oGenericAlgorithm = new GenericAlgorithm();
            bool found = oGenericAlgorithm.SearchResult(1);
            cbbRoom.Enabled = true;
            bntStart.Enabled = true;

            if (!cbbRoom.Enabled)
            {
                if (DialogResult.OK == MessageBox.Show("Không tìm thấy kết quả!\r\nBạn có muồn thử lại không?", "Thông báo", MessageBoxButtons.OKCancel, MessageBoxIcon.Information))
                    bntStart_Click(sender, e);
            }
            else
            {
                cbbRoom.SelectedIndex = 0;
                cbbRoom.Focus();
            }
        }
        // Xem kết quả thời khóa biểu theo từng phòng.
        private void cbbRoom_SelectedIndexChanged(object sender, EventArgs e)
        {
            ShowSchedule(cbbRoom.SelectedIndex);
        }
        // Hiển thị thời khóa biểu của 1 phòng học dưới dạng lưới dữ liệu.
        void ShowSchedule(int pIndexRoom)
        {
            if (pIndexRoom < 0)
                return;
            Individual schedule = oGenericAlgorithm.ScheduleResult;
            if (schedule == null)
                return;
            DataTable dt = new DataTable();
            int iUnitCount = inputData.NumSession * inputData.NumPeriod;
            // Tạo 10 cột ứng với 10 tiết học.
            for (int i = 1; i <= iUnitCount; i++)
            {
                dt.Columns.Add("Tiết " + i);
            }
            int iUnit = pIndexRoom * (inputData.NumDay * iUnitCount);
            for (int i = 0; i < inputData.NumDay; i++)
            {
                DataRow row = dt.NewRow();
                dt.Rows.Add(row);
                for (int j = 0; j < iUnitCount; j++)
                {
                    if (schedule.PeriodErrors[iUnit] > 0)
                        row.SetColumnError(j, "Số lỗi: " + schedule.PeriodErrors[iUnit]);
                    row[j] = ConvertEventValue(schedule.Schedule[iUnit++]);
                }
                //rowThu.ItemArray = a;
            }
            dataGridView1.DataSource = dt;
            label2.Text = "Số sự kiện: " + inputData.LstEvent.Count;
            label4.Text = "Số thích nghi: " + schedule.NumError;
            label5.Text = "Số lần lặp: " + oGenericAlgorithm.NumLoop;
        }
        #endregion Tương tác với người dùng.
    }
}
